# -*- coding: utf-8 -*-
"""
车辆标定状态检测数据模块
负责检查各种传感器和系统环境的数据有效性
"""

from typing import Dict, List, Any, Tuple
import re
from gglobal import logger, config
from ..handlercore.language_manager import LanguageManager


class CalibrationDataChecker:
    """
    车辆标定数据检测器
    负责检查各种传感器数据和系统环境的有效性
    """
    
    def __init__(self):
        """初始化数据检测器"""
        self.calibration_data = {}
        self.last_check_time = None
        
        # 初始化语言管理器
        self.language_manager = LanguageManager()
        
        # 数据检测项的翻译键映射（内部使用英文键，显示时翻译）
        self.data_detection_keys = {
            "top_laser": "data_detection_top_laser",
            "bottom_laser": "data_detection_bottom_laser", 
            "mid360": "data_detection_mid360",
            "left_fork_camera": "data_detection_left_fork_camera",
            "right_fork_camera": "data_detection_right_fork_camera",
            "system_environment": "data_detection_system_environment"
        }
        
        # 标定项目与检测数据的映射关系（使用内部键）
        self.calibration_requirements = {
            "calibration_menu_laser_yaw": ["top_laser", "system_environment"],
            "calibration_menu_laser_joint": ["top_laser", "bottom_laser", "system_environment"],
            "calibration_menu_mid360": ["top_laser", "mid360", "system_environment"],
            "calibration_menu_fork_camera": ["left_fork_camera", "right_fork_camera", "mid360", "system_environment"],
            "calibration_menu_fork_camera_sub1": ["left_fork_camera", "right_fork_camera", "mid360", "system_environment"],
            "calibration_menu_recognition_camera_sub1": ["left_fork_camera", "right_fork_camera", "mid360", "system_environment"],
            "calibration_menu_recognition_camera_sub2": ["left_fork_camera", "right_fork_camera", "mid360", "system_environment"]
        }
        
        # 数据检测项与参数键的映射（使用内部键）
        self.data_param_mapping = {
            "top_laser": "rslidar_points",
            "bottom_laser": ["scan_init_down", "scan_down_left", "scan_down_right"],
            "mid360": "livox_lidar",
            "left_fork_camera": ["camera1_depth_points", "camera1_color_image_raw"],
            "right_fork_camera": ["camera2_depth_points", "camera2_color_image_raw"],
            "system_environment": ["system_version", "kernel_version"]
        }
    
    def get_translated_data_name(self, internal_key: str) -> str:
        """
        获取数据检测项的翻译名称
        
        Args:
            internal_key: 内部键名
            
        Returns:
            str: 翻译后的显示名称
        """
        translation_key = self.data_detection_keys.get(internal_key, internal_key)
        return self.language_manager.get_text(translation_key, internal_key)
    
    def get_translated_requirements(self, calibration_key: str) -> List[str]:
        """
        获取指定标定项的翻译后检测数据要求
        
        Args:
            calibration_key: 标定项键值
            
        Returns:
            List[str]: 翻译后的检测数据要求列表
        """
        internal_requirements = self.calibration_requirements.get(calibration_key, [])
        return [self.get_translated_data_name(key) for key in internal_requirements]
    
    def refresh_calibration_data(self) -> bool:
        """
        从参数管理器刷新标定数据
        
        Returns:
            bool: 刷新是否成功
        """
        try:
            logger.info("开始刷新车辆标定数据...")
            
            # 从参数管理器获取标定检查数据
            self.calibration_data = config.get_param("car_calibration_check", {})
            
            if not self.calibration_data:
                logger.warning("未找到车辆标定检查数据，使用默认值")
                self.calibration_data = self._get_default_calibration_data()
            
            import time
            self.last_check_time = time.time()
            
            logger.info("车辆标定数据刷新完成")
            return True
            
        except Exception as e:
            logger.error(f"刷新车辆标定数据失败: {str(e)}")
            return False
    
    def _get_default_calibration_data(self) -> Dict[str, Any]:
        """
        获取默认的标定数据结构
        
        Returns:
            Dict[str, Any]: 默认标定数据
        """
        return {
            "system_version": "",
            "kernel_version": "",
            "mooe-core": "",
            "rslidar_points": False,
            "scan_init_down": False,
            "scan_down_left": False,
            "scan_down_right": False,
            "livox_lidar": False,
            "camera1_depth_points": False,
            "camera2_depth_points": False,
            "camera1_color_image_raw": False,
            "camera2_color_image_raw": False
        }
    
    def check_data_validity(self, data_name: str) -> bool:
        """
        检查指定数据项的有效性 - 增强调试日志
        
        Args:
            data_name: 数据项名称（内部键）
            
        Returns:
            bool: 数据是否有效
        """
        logger.debug(f"[CalibrationDataChecker] 检查数据有效性: {data_name}")
        
        if data_name not in self.data_param_mapping:
            logger.warning(f"未知的数据项: {data_name}")
            return False
        
        param_keys = self.data_param_mapping[data_name]
        logger.debug(f"[CalibrationDataChecker] 数据项 {data_name} 对应参数键: {param_keys}")
        
        # 如果是单个参数键
        if isinstance(param_keys, str):
            result = self._check_single_param(param_keys, data_name)
            logger.debug(f"[CalibrationDataChecker] 单参数检查结果 {data_name}: {result}")
            return result
        
        # 如果是多个参数键的列表
        elif isinstance(param_keys, list):
            result = self._check_multiple_params(param_keys, data_name)
            logger.debug(f"[CalibrationDataChecker] 多参数检查结果 {data_name}: {result}")
            return result
        
        logger.warning(f"[CalibrationDataChecker] 数据项 {data_name} 的参数键类型不支持: {type(param_keys)}")
        return False
    
    def _check_single_param(self, param_key: str, data_name: str) -> bool:
        """
        检查单个参数的有效性 - 增强调试日志
        
        Args:
            param_key: 参数键
            data_name: 数据项名称
            
        Returns:
            bool: 参数是否有效
        """
        value = self.calibration_data.get(param_key, False)
        logger.debug(f"[CalibrationDataChecker] 单参数检查 {data_name}.{param_key}: {value}")
        
        # 对于系统环境的特殊检查
        if data_name == "system_environment":
            if param_key == "system_version":
                result = "ubuntu 16.04" in str(value).lower()
                logger.debug(f"[CalibrationDataChecker] 系统版本检查 {param_key}: '{value}' -> {result}")
                return result
            elif param_key == "kernel_version":
                result = "x86_64" in str(value).lower()
                logger.debug(f"[CalibrationDataChecker] 内核版本检查 {param_key}: '{value}' -> {result}")
                return result
        
        # 对于布尔值参数
        result = bool(value)
        logger.debug(f"[CalibrationDataChecker] 布尔值检查 {param_key}: {value} -> {result}")
        return result
    
    def _check_multiple_params(self, param_keys: List[str], data_name: str) -> bool:
        """
        检查多个参数的有效性 - 增强调试日志
        
        Args:
            param_keys: 参数键列表
            data_name: 数据项名称
            
        Returns:
            bool: 参数是否有效
        """
        logger.debug(f"[CalibrationDataChecker] 多参数检查 {data_name}: {param_keys}")
        
        if data_name == "bottom_laser":
            # 下激光数据：scan_init_down == True 或者 (scan_down_left == True 且 scan_down_right == True)
            scan_init_down = self.calibration_data.get("scan_init_down", False)
            scan_down_left = self.calibration_data.get("scan_down_left", False)
            scan_down_right = self.calibration_data.get("scan_down_right", False)
            
            logger.debug(f"[CalibrationDataChecker] 下激光检查: scan_init_down={scan_init_down}, scan_down_left={scan_down_left}, scan_down_right={scan_down_right}")
            
            result = scan_init_down or (scan_down_left and scan_down_right)
            logger.debug(f"[CalibrationDataChecker] 下激光检查结果: {result}")
            return result
        
        elif data_name in ["left_fork_camera", "right_fork_camera"]:
            # 叉臂相机：深度点云和彩色图像都必须有效
            param_values = {key: self.calibration_data.get(key, False) for key in param_keys}
            logger.debug(f"[CalibrationDataChecker] {data_name}检查参数值: {param_values}")
            
            result = all(self.calibration_data.get(key, False) for key in param_keys)
            logger.debug(f"[CalibrationDataChecker] {data_name}检查结果: {result}")
            return result
        
        elif data_name == "system_environment":
            # 系统环境：系统版本包含Ubuntu 16.04且内核版本包含x86_64
            system_version = str(self.calibration_data.get("system_version", "")).lower()
            kernel_version = str(self.calibration_data.get("kernel_version", "")).lower()
            
            logger.debug(f"[CalibrationDataChecker] 系统环境检查: system_version='{system_version}', kernel_version='{kernel_version}'")
            
            m = re.search(r"ubuntu\s*(\d+)\.(\d+)", system_version, re.IGNORECASE)
            if m:
                major = int(m.group(1))
                minor = int(m.group(2))
                ubuntu_valid = (major > 16) or (major == 16 and minor >= 4)
            else:
                ubuntu_valid = False
            arch_valid = "x86_64" in kernel_version
            
            logger.debug(f"[CalibrationDataChecker] 系统环境检查详情: ubuntu_valid={ubuntu_valid}, arch_valid={arch_valid}")
            
            result = ubuntu_valid and arch_valid
            logger.debug(f"[CalibrationDataChecker] 系统环境检查结果: {result}")
            return result
        
        # 默认情况：所有参数都必须为True
        param_values = {key: self.calibration_data.get(key, False) for key in param_keys}
        logger.debug(f"[CalibrationDataChecker] 默认多参数检查 {data_name}: {param_values}")
        
        result = all(self.calibration_data.get(key, False) for key in param_keys)
        logger.debug(f"[CalibrationDataChecker] 默认多参数检查结果 {data_name}: {result}")
        return result
    
    def get_calibration_requirements(self, calibration_key: str) -> List[str]:
        """
        获取指定标定项的检测数据要求
        
        Args:
            calibration_key: 标定项键值
            
        Returns:
            List[str]: 检测数据要求列表
        """
        return self.calibration_requirements.get(calibration_key, [])
    
    def check_calibration_readiness(self, calibration_key: str) -> Tuple[bool, Dict[str, bool]]:
        """
        检查指定标定项的准备状态
        
        Args:
            calibration_key: 标定项键值
            
        Returns:
            Tuple[bool, Dict[str, bool]]: (是否准备就绪, 各检测项状态详情)
        """
        requirements = self.get_calibration_requirements(calibration_key)
        if not requirements:
            logger.warning(f"未找到标定项 {calibration_key} 的检测要求")
            return False, {}
        
        # 检查每个检测项的状态
        status_details = {}
        all_ready = True
        
        for requirement in requirements:
            is_valid = self.check_data_validity(requirement)
            status_details[requirement] = is_valid
            if not is_valid:
                all_ready = False
        
        logger.info(f"标定项 {calibration_key} 准备状态: {all_ready}, 详情: {status_details}")
        return all_ready, status_details
    
    def get_global_disable_conditions(self) -> List[str]:
        """
        获取全局禁用条件（影响所有标定按钮的数据项）
        
        Returns:
            List[str]: 全局关键数据项列表（内部键）
        """
        return ["mid360", "system_environment", "top_laser", "bottom_laser"]
    
    def should_disable_all_calibration(self) -> Tuple[bool, List[str]]:
        """
        检查是否应该禁用所有标定功能
        
        Returns:
            Tuple[bool, List[str]]: (是否应该禁用, 异常的数据项列表)
        """
        global_conditions = self.get_global_disable_conditions()
        failed_conditions = []
        
        for condition in global_conditions:
            if not self.check_data_validity(condition):
                failed_conditions.append(condition)
        
        should_disable = len(failed_conditions) > 0
        
        if should_disable:
            logger.warning(f"全局禁用条件触发，异常数据项: {failed_conditions}")
        
        return should_disable, failed_conditions
    
    def get_detection_status_summary(self) -> Dict[str, Any]:
        """
        获取检测状态摘要
        
        Returns:
            Dict[str, Any]: 检测状态摘要信息
        """
        summary = {
            "last_check_time": self.last_check_time,
            "data_status": {},
            "global_disable": False,
            "failed_global_conditions": []
        }
        
        # 检查所有数据项状态
        for data_name in self.data_param_mapping.keys():
            summary["data_status"][data_name] = self.check_data_validity(data_name)
        
        # 检查全局禁用条件
        should_disable, failed_conditions = self.should_disable_all_calibration()
        summary["global_disable"] = should_disable
        summary["failed_global_conditions"] = failed_conditions
        
        return summary
    
    def get_calibration_data_raw(self) -> Dict[str, Any]:
        """
        获取原始标定数据
        
        Returns:
            Dict[str, Any]: 原始标定数据
        """
        return self.calibration_data.copy()
    
    def update_calibration_data(self, new_data: Dict[str, Any]) -> bool:
        """
        更新标定数据并保存到参数管理器
        
        Args:
            new_data: 新的标定数据
            
        Returns:
            bool: 更新是否成功
        """
        try:
            # 更新本地数据
            self.calibration_data.update(new_data)
            
            # 保存到参数管理器
            config.set_param("car_calibration_check", self.calibration_data)
            
            import time
            self.last_check_time = time.time()
            
            logger.info("标定数据更新成功")
            return True
            
        except Exception as e:
            logger.error(f"更新标定数据失败: {str(e)}")
            return False